package tech.dongling.boot.ioc;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

/**
 * 包扫描器，用于扫描指定包下的所有类
 */
public class PackageScanner {
    private static final Logger logger = LoggerFactory.getLogger(PackageScanner.class);

    /**
     * 扫描指定包下的所有类
     */
    public static Set<Class<?>> scanClasses(String basePackage) {
        Set<Class<?>> classes = new HashSet<>();

        try {
            // 获取类加载器
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

            // 将包名转换为路径
            String packagePath = basePackage.replace('.', '/');
            URL url = classLoader.getResource(packagePath);

            if (url == null) {
                logger.warn("Package not found: {}", basePackage);
                return classes;
            }

            // 扫描目录
            if ("file".equals(url.getProtocol())) {
                scanDirectory(new File(url.getFile()), basePackage, classes, classLoader);
            }

        } catch (Exception e) {
            logger.error("Error scanning package {}: {}", basePackage, e.getMessage(), e);
        }

        return classes;
    }

    /**
     * 扫描目录
     */
    private static void scanDirectory(File directory, String packageName, Set<Class<?>> classes, ClassLoader classLoader) {
        if (!directory.exists() || !directory.isDirectory()) {
            return;
        }

        File[] files = directory.listFiles();
        if (files == null) {
            return;
        }

        for (File file : files) {
            String fileName = file.getName();

            if (file.isDirectory()) {
                // 递归扫描子目录
                scanDirectory(file, packageName + "." + fileName, classes, classLoader);
            } else if (fileName.endsWith(".class")) {
                // 加载类文件
                String className = packageName + "." + fileName.substring(0, fileName.length() - 6);
                loadClass(className, classes, classLoader);
            }
        }
    }

    /**
     * 加载类
     */
    private static void loadClass(String className, Set<Class<?>> classes, ClassLoader classLoader) {
        try {
            Class<?> clazz = classLoader.loadClass(className);

            // 过滤掉接口、抽象类、内部类等
            if (!clazz.isInterface() && !clazz.isEnum() && !clazz.isAnnotation()
                    && !clazz.isAnonymousClass() && !clazz.isLocalClass()) {
                classes.add(clazz);
                logger.debug("Loaded class: {}", className);
            }
        } catch (ClassNotFoundException e) {
            logger.warn("Class not found: {}", className);
        } catch (Exception e) {
            logger.error("Error loading class {}: {}", className, e.getMessage());
        }
    }
} 